#include "Model.h"

Model::Model(QObject *parent)
    : QObject(parent)
{
    m_saveDirPath = QStandardPaths::writableLocation(QStandardPaths::StandardLocation::AppLocalDataLocation);

    loadData();
}

Model::~Model()
{

}

QList<Question> Model::GetQuestionList()
{
    return m_questionList;
}

Question Model::AddQuestion(const QString &question, const QString &answer)
{
    Question q;
    q.Question = question;
    q.Answer = answer;
    q.AddedDateTime = QDateTime::currentDateTime().toString(DateTimeFormationStr);

    m_questionList.append(q);

    saveData();
}

void Model::DeleteQuestion(int index)
{
    m_questionList.removeAt(index);

    saveData();
}

void Model::ModifyQuestion(int index, const QString &question, const QString &answer)
{
    Question q = m_questionList.at(index);
    q.Question = question;
    q.Answer = answer;
    m_questionList.replace(index, q);

    saveData();
}

void Model::ModifyQuestionWrongCount(int index, int wrongCount)
{
    Question q = m_questionList.at(index);
    q.WrongCount = wrongCount;
    m_questionList.replace(index, q);

    saveData();
}

void Model::saveData()
{
    QJsonArray jsonArray;
    for (const Question &q : m_questionList) {
        QJsonObject obj;
        obj.insert("Question", q.Question);
        obj.insert("Answer", q.Answer);
        obj.insert("AddedDateTime", q.AddedDateTime);
        obj.insert("WrongCount", q.WrongCount);

        jsonArray.append(obj);
    }
    QJsonDocument doc(jsonArray);
    const QByteArray &ba = doc.toJson();

    QDir dir;
    if (!dir.exists(m_saveDirPath)) {
        dir.mkpath(m_saveDirPath);
    }

    const QString &questionFilePath = QString("%1/%2").arg(m_saveDirPath).arg(QuestionFileName);
    QFile f(questionFilePath);
    if (!f.open(QIODevice::OpenModeFlag::WriteOnly)) {
        qCritical() << Q_FUNC_INFO << questionFilePath << "open failed!";
        return;
    }

    f.write(ba);
    f.close();
}

void Model::loadData()
{
    const QString &questionFilePath = QString("%1/%2").arg(m_saveDirPath).arg(QuestionFileName);
    QFile f(questionFilePath);
    if (!f.exists()) {
        return;
    }
    if (!f.open(QIODevice::OpenModeFlag::ReadOnly)) {
        qCritical() << Q_FUNC_INFO << questionFilePath << "open failed!";
        return;
    }
    const QByteArray &ba = f.readAll();
    f.close();

    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(ba, &error);
    if (error.error != QJsonParseError::ParseError::NoError) {
        qCritical() << Q_FUNC_INFO << "json parse error, error type:" << error.error;
        return;
    }
    QJsonArray jsonArray = doc.array();
    for (const QJsonValue &jsonValue : jsonArray) {
        const QJsonObject jsonObj = jsonValue.toObject();
        Question q;
        q.Question = jsonObj.value("Question").toString();
        q.Answer = jsonObj.value("Answer").toString();
        q.AddedDateTime = jsonObj.value("AddedDateTime").toString();
        q.WrongCount = jsonObj.value("WrongCount").toInt();

        m_questionList.append(q);
    }

    std::sort(m_questionList.begin(), m_questionList.end(), [](const Question &a, const Question &b) {
        return a.AddedDateTime < b.AddedDateTime;
    });
}
